home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / dopus412-gpl / config / main5.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  40KB  |  1,495 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "config.h"
  32.  
  33. dofiletypeconfig()
  34. {
  35.     ULONG class;
  36.     USHORT code,gadgetid;
  37.     struct ConfigUndo *undo;
  38.     struct DOpusRemember *key;
  39.     struct DOpusListView *view;
  40.     struct dopusfiletype *type,*tpos,*type1;
  41.     struct fileclass *fclass,classbuf;
  42.     int mode=-1,a,classchange=0;
  43.     char **listptr,buf[256],*ptr;
  44.  
  45.     key=NULL; type1=NULL; firstclass=NULL;
  46.     filetypeactionlist.items=NULL;
  47.     filetypeactionlist.topitem=0;
  48.     showconfigscreen(CFG_FILETYPE);
  49.     ClearMenuStrip(Window);
  50.     projectmenu.NextMenu=&classmenu;
  51.     FSSetMenuStrip(Window,&projectmenu);
  52.     listptr=makefiletypelist(&key);
  53.     undo=makeundo(UNDO_FILETYPE);
  54.     showtypelist(listptr);
  55.     busy();
  56.     readfileclasses();
  57.     unbusy();
  58.  
  59.     FOREVER {
  60.         Wait(1<<Window->UserPort->mp_SigBit);
  61.         while (IMsg=getintuimsg()) {
  62.             if ((view=ListViewIDCMP(&filetypeactionlist,IMsg))==(struct DOpusListView *)-1) {
  63.                 class=IMsg->Class; code=IMsg->Code;
  64.                 if (class==GADGETUP || class==GADGETDOWN)
  65.                     gadgetid=((struct Gadget *)IMsg->IAddress)->GadgetID;
  66.                 ReplyMsg((struct Message *)IMsg);
  67.                 switch (class) {
  68.                     case MENUPICK:
  69.                         if (code==MENUNULL) break;
  70.                         switch (MENUNUM(code)) {
  71.                             case 0:
  72.                                 if (type1) {
  73.                                     showtypelist(listptr);
  74.                                     type1=NULL;
  75.                                 }
  76.                                 if (mode>-1) {
  77.                                     select_gadget(&maingad[mode],0);
  78.                                     mode=-1;
  79.                                 }
  80.                                 dogadgetinfo(NULL);
  81.                                 switch ((a=ITEMNUM(code))) {
  82.                                     case 0:
  83.                                     case 1:
  84.                                         if (doload(CFG_FILETYPE,a)) {
  85.                                             listptr=makefiletypelist(&key);
  86.                                             showtypelist(listptr);
  87.                                             if (a) dogadgetinfo(cfg_string[STR_NEW_FILETYPES_MERGED]);
  88.                                             else dogadgetinfo(cfg_string[STR_DEFAULT_FILETYPES_MERGED]);
  89.                                         }
  90.                                         break;
  91.                                 }
  92.                                 break;
  93.                             case 1:
  94.                                 switch (ITEMNUM(code)) {
  95.                                     case 0:
  96.                                         classbuf.type[0]=0;
  97.                                         classbuf.typeid[0]=0;
  98.                                         classbuf.recognition=NULL;
  99.                                         classbuf.next=classbuf.last=NULL;
  100.                                         if (editclass(&classbuf,1)) classchange=1;
  101.                                         break;
  102.                                     case 1:
  103.                                         if (!(fclass=getfileclasslist(1))) break;
  104.                                         if (editclass(fclass,0)) classchange=1;
  105.                                         break;
  106.                                     case 2:
  107.                                         if (!(fclass=getfileclasslist(3))) break;
  108.                                         CopyMem((char *)fclass,(char *)&classbuf,sizeof(struct fileclass));
  109.                                         classbuf.recognition=getcopy(fclass->recognition,-1,NULL);
  110.                                         classbuf.next=classbuf.last=NULL;
  111.                                         if (editclass(&classbuf,1)) classchange=1;
  112.                                         break;
  113.                                     case 3:
  114.                                         if (!(fclass=getfileclasslist(2))) break;
  115.                                         lsprintf(buf,"\"%s\"\n%s",
  116.                                             fclass->type,cfg_string[STR_REALLY_DELETE_THIS_CLASS]);
  117.                                         if (request(buf)) {
  118.                                             dogadgetinfo(cfg_string[STR_FILE_CLASS_DELETED]);
  119.                                             removefileclass(fclass);
  120.                                             classchange=1;
  121.                                         }
  122.                                         else dogadgetinfo(NULL);
  123.                                         break;
  124.                                     case 5:
  125.                                         if (importfileclasses()) classchange=1;
  126.                                         break;
  127.                                     case 6:
  128.                                         busy();
  129.                                         if (savefileclasses()) classchange=0;
  130.                                         unbusy();
  131.                                         break;
  132.                                     case 7:
  133.                                         strcpy(dirbuf,classname);
  134.                                         if (ptr=BaseName(dirbuf)) {
  135.                                             strcpy(filebuf,ptr);
  136.                                             *ptr=0;
  137.                                         }
  138.                                         else filebuf[0]=0;
  139.                                         filereq.flags=0;
  140.                                         filereq.title=cfg_string[STR_ENTER_NAME_TO_SAVE_CLASSES];
  141.                                         filereq.window=Window;
  142.                                         if (!(FileRequest(&filereq)) || !filebuf[0]) break;
  143.                                         strcpy(classname,dirbuf);
  144.                                         TackOn(classname,filebuf,256);
  145.                                         busy();
  146.                                         if (savefileclasses()) classchange=0;
  147.                                         unbusy();
  148.                                         break;
  149.                                     case 8:
  150.                                         if (firstclass && (request(cfg_string[STR_ERASE_ALL_CLASSES]))) {
  151.                                             freefileclasses();
  152.                                             classchange=0;
  153.                                         }
  154.                                         break;
  155.                                 }
  156.                                 break;
  157.                         }
  158.                         break;
  159.                     case GADGETUP:
  160.                         if (gadgetid<FILETYPE_OKAY) {
  161.                             if (type1) {
  162.                                 showtypelist(listptr);
  163.                                 type1=NULL;
  164.                             }
  165.                             if (mode==gadgetid) {
  166.                                 mode=-1;
  167.                                 dogadgetinfo(NULL);
  168.                                 break;
  169.                             }
  170.                             if (mode>-1) {
  171.                                 select_gadget(&maingad[mode],0);
  172.                             }
  173.                         }
  174.                         switch (gadgetid) {
  175.                             case FILETYPE_OKAY:
  176.                             case FILETYPE_CANCEL:
  177.                                 if (classchange && !(request(cfg_string[STR_EXIT_WITHOUT_SAVING_CLASSES])))
  178.                                     break;
  179.                                 if (gadgetid==FILETYPE_CANCEL) doundo(undo,UNDO_FILETYPE);
  180.                                 doundo(undo,0);
  181.                                 RemoveListView(&filetypeactionlist,1);
  182.                                 LFreeRemember(&key);
  183.                                 freefileclasses();
  184.                                 ClearMenuStrip(Window); projectmenu.NextMenu=NULL;
  185.                                 FSSetMenuStrip(Window,&projectmenu);
  186.                                 return((gadgetid==FILETYPE_OKAY));
  187.                             case FILETYPE_NEW:
  188.                                 if (!(fclass=getfileclasslist(0))) break;
  189.                                 type=firsttype;
  190.                                 while (type) {
  191.                                     if (strcmp(type->type,fclass->type)==0) break;
  192.                                     type=type->next;
  193.                                 }
  194.                                 if (!type || request(cfg_string[STR_REDEFINE_EXISTING_CLASS_ACTION])) {
  195.                                     if (type=AllocMem(sizeof(struct dopusfiletype),MEMF_CLEAR)) {
  196.                                         strcpy(type->type,fclass->type);
  197.                                         strcpy(type->typeid,fclass->typeid);
  198.                                         type->recognition=getcopy(fclass->recognition,-1,&typekey);
  199.                                         for (a=0;a<4;a++) {
  200.                                             type->stack[a]=4000;
  201.                                             type->delay[a]=2;
  202.                                         }
  203.                                         if (editfiletype(type,&key,1)) {
  204.                                             if (tpos=(struct dopusfiletype *)
  205.                                                     getcopy((char *)type,sizeof(struct dopusfiletype),&typekey)) {
  206.                                                 tpos->recognition=getcopy(type->recognition,-1,&typekey);
  207.                                                 for (a=0;a<4;a++)
  208.                                                     tpos->function[a]=getcopy(type->function[a],-1,&typekey);
  209.                                                 addfiletype(tpos);
  210.                                             }
  211.                                         }
  212.                                         FreeMem(type,sizeof(struct dopusfiletype));
  213.                                         listptr=makefiletypelist(&key);
  214.                                         showtypelist(listptr);
  215.                                     }
  216.                                 }
  217.                                 break;
  218.                         }
  219.                         mode=doinitfiletypetext(gadgetid);
  220.                         break;
  221.                 }
  222.             }
  223.             else if (view) {
  224.                 if (view->listid==2) {
  225.                     if (view->itemselected>-1) {
  226.                         type=firsttype;
  227.                         for (a=0;a<view->itemselected;a++,type=type->next)
  228.                             if (!type) break;
  229.                         if (type) {
  230.                             switch (mode) {
  231.                                 case -1:
  232.                                     editfiletype(type,&key,0);
  233.                                     listptr=makefiletypelist(&key);
  234.                                     showtypelist(listptr);
  235.                                     break;
  236.                                 case FILETYPE_SWAP:
  237.                                     if (type1) {
  238.                                         if (strcmp(type->type,"Default")==0)
  239.                                             dogadgetinfo(cfg_string[STR_DEFAULT_ACTION_CAN_NOT_BE_MOVED]);
  240.                                         else if (type!=type1) {
  241.                                             SwapMem((char *)type->type,(char *)type1->type,sizeof(struct dopusfiletype)-4);
  242.                                             listptr=makefiletypelist(&key);
  243.                                             dogadgetinfo(cfg_string[STR_CLASS_ACTIONS_SWAPPED]);
  244.                                         }
  245.                                         else dogadgetinfo(NULL);
  246.                                         showtypelist(listptr);
  247.                                         type1=NULL;
  248.                                     }
  249.                                     else {
  250.                                         if (strcmp(type->type,"Default")==0) {
  251.                                             showtypelist(listptr);
  252.                                             dogadgetinfo(cfg_string[STR_DEFAULT_ACTION_CAN_NOT_BE_MOVED]);
  253.                                         }
  254.                                         else {
  255.                                             type1=type;
  256.                                             dogadgetinfo(cfg_string[STR_SELECT_ACTION_TO_SWAP_WITH_FIRST]);
  257.                                         }
  258.                                     }
  259.                                     break;
  260.                                 case FILETYPE_DELETE:
  261.                                     if (request(cfg_string[STR_REALLY_DELETE_THIS_ACTION])) {
  262.                                         if (type==firsttype) firsttype=type->next;
  263.                                         else {
  264.                                             tpos=firsttype;
  265.                                             while (tpos) {
  266.                                                 if (tpos->next==type) {
  267.                                                     tpos->next=type->next;
  268.                                                     break;
  269.                                                 }
  270.                                                 tpos=tpos->next;
  271.                                             }
  272.                                         }
  273.                                         dogadgetinfo(cfg_string[STR_ACTION_DELETED]);
  274.                                         listptr=makefiletypelist(&key);
  275.                                     }
  276.                                     else dogadgetinfo(NULL);
  277.                                     showtypelist(listptr);
  278.                                     break;
  279.                             }
  280.                         }
  281.                     }
  282.                 }
  283.             }
  284.         }
  285.     }
  286. }
  287.     
  288. char **makefiletypelist(key)
  289. struct DOpusRemember **key;
  290. {
  291.     char **list;
  292.     int count,a;
  293.     struct dopusfiletype *type;
  294.  
  295.     LFreeRemember(key);
  296.     type=firsttype;
  297.     for (count=0;type;count++,type=type->next);
  298.     if (!(list=LAllocRemember(key,(count+1)*4,MEMF_CLEAR))) return(NULL);
  299.     type=firsttype;
  300.     for (a=0;a<count;a++) {
  301.         if (list[a]=LAllocRemember(key,60,MEMF_CLEAR)) {
  302.             if (type->type[0]) lsprintf(list[a],"%-50s%s",type->type,type->typeid);
  303.             else {
  304.                 list[a][0]=' '; list[a][1]=0;
  305.             }
  306.         }
  307.         type=type->next;
  308.     }
  309.     return(list);
  310. }
  311.  
  312. void showtypelist(list)
  313. char **list;
  314. {
  315.     filetypeactionlist.items=list; filetypeactionlist.itemselected=-1;
  316.     RefreshListView(&filetypeactionlist,1);
  317. }
  318.  
  319. doinitfiletypetext(id)
  320. int id;
  321. {
  322.     int mode=-1;
  323.  
  324.     switch (id) {
  325.         case FILETYPE_SWAP:
  326.             mode=FILETYPE_SWAP;
  327.             dogadgetinfo(cfg_string[STR_SELECT_ACTION_TO_SWAP]);
  328.             break;
  329.         case FILETYPE_DELETE:
  330.             mode=FILETYPE_DELETE;
  331.             dogadgetinfo(cfg_string[STR_SELECT_ACTION_TO_DELETE]);
  332.             break;
  333.     }
  334.     return(mode);
  335. }
  336.  
  337. void filetypetitle(type)
  338. struct dopusfiletype *type;
  339. {
  340.     char title[80];
  341.  
  342.     lsprintf(title,"%s : %s",cfg_string[STR_FILETYPE_CLASS],type->type);
  343.     if (type->typeid[0]) {
  344.         char extra[16];
  345.  
  346.         lsprintf(extra," (%s)",type->typeid);
  347.         strcat(title,extra);
  348.     }
  349.     doscreentitle(title);
  350. }
  351.  
  352. editfiletype(type,key,new)
  353. struct dopusfiletype *type;
  354. struct DOpusRemember **key;
  355. int new;
  356. {
  357.     struct dopusfunction editbuf;
  358.     char *func[FILETYPE_FUNCNUM],*oldfunc[FILETYPE_FUNCNUM];
  359.     int a,b;
  360.  
  361.     RemoveListView(&filetypeactionlist,1);
  362.     cleanconfigscreen();
  363.     filetypetitle(type);
  364.     editbuf.function=NULL;
  365.     for (a=0;a<FILETYPE_FUNCNUM;a++) {
  366.         oldfunc[a]=type->function[a];
  367.         func[a]=getcopy(type->function[a],-1,NULL);
  368.         type->function[a]=func[a];
  369.     }
  370.     b=editfunction(&editbuf,CFG_FILETYPE,type);
  371.     if (new) {
  372.         if (!b) {
  373.             for (a=0;a<FILETYPE_FUNCNUM;a++) {
  374.                 func[a]=oldfunc[a];
  375.                 freestring(type->function[a]);
  376.                 type->function[a]=func[a];
  377.             }
  378.         }
  379.     }
  380.     else {
  381.         for (a=0;a<FILETYPE_FUNCNUM;a++) {
  382.             if (b) func[a]=getcopy(type->function[a],-1,&typekey);
  383.             else func[a]=oldfunc[a];
  384.             freestring(type->function[a]);
  385.             type->function[a]=func[a];
  386.         }
  387.     }
  388.     showconfigscreen(CFG_FILETYPE);
  389.     return(b);
  390. }
  391.  
  392. editclass(class,new)
  393. struct fileclass *class;
  394. int new;
  395. {
  396.     struct fileclass editbuf;
  397.     int b,c;
  398.  
  399.     makehelpname(cfg_string[STR_EDIT_CLASS]);
  400.     if (new==-1) {
  401.         new=c=0;
  402.     }
  403.     else {
  404.         c=1;
  405.         RemoveListView(&filetypeactionlist,2);
  406.     }
  407.     cleanconfigscreen();
  408.     doscreentitle(cfg_string[STR_FILE_CLASS_EDIT_SCREEN]);
  409.     strcpy(editbuf.type,class->type);
  410.     strcpy(editbuf.typeid,class->typeid);
  411.     editbuf.recognition=getcopy(class->recognition,-1,NULL);
  412.     if ((b=editfileclass(&editbuf,new))) {
  413.         if (c) {
  414.             if (!new) removefileclass(class);
  415.             addfileclass(editbuf.type,editbuf.typeid,editbuf.recognition);
  416.         }
  417.         else {
  418.             freestring(class->recognition);
  419.             class->recognition=getcopy(editbuf.recognition,-1,NULL);
  420.             strcpy(class->type,editbuf.type);
  421.             strcpy(class->typeid,editbuf.typeid);
  422.         }
  423.     }
  424.     if (c) showconfigscreen(CFG_FILETYPE);
  425.     freestring(editbuf.recognition);
  426.     makehelpname((char *)-1);
  427.     return(b);
  428. }
  429.  
  430. void addfiletype(type)
  431. struct dopusfiletype *type;
  432. {
  433.     struct dopusfiletype *tpos;
  434.  
  435.     if (!(tpos=firsttype)) firsttype=type;
  436.     else {
  437.         while (tpos->next) {
  438.             if (strcmp(tpos->next->type,"Default")==0) {
  439.                 type->next=tpos->next;
  440.                 break;
  441.             }
  442.             tpos=tpos->next;
  443.         }
  444.         tpos->next=type;
  445.     }
  446. }
  447.  
  448. void readfileclasses()
  449. {
  450.     int in,size,pos,lsize,a;
  451.     char *classbuf,buf[256],*typeid;
  452.  
  453.     if ((CheckExist(classname,&size))>=0 ||
  454.         !(classbuf=AllocMem(size,MEMF_CLEAR))) return;
  455.     if (in=Open(classname,MODE_OLDFILE)) {
  456.         Read(in,classbuf,size);
  457.         Close(in);
  458.         pos=0;
  459.         FOREVER {
  460.             if ((pos=readline(classbuf,pos,buf,size))==-1) break;
  461.             typeid="";
  462.             for (a=0;buf[a];a++) {
  463.                 if (buf[a]==1) {
  464.                     buf[a]=0;
  465.                     typeid=&buf[a+1];
  466.                     break;
  467.                 }
  468.             }
  469.             for (lsize=pos;lsize<size;lsize++) if (!classbuf[lsize]) break;
  470.             if (!(addfileclass(buf,typeid,&classbuf[pos]))) break;
  471.             pos=lsize+1;
  472.         }
  473.     }
  474.     FreeMem(classbuf,size);
  475. }
  476.  
  477. importfileclasses()
  478. {
  479.     int in,size,pos,lsize,num,a,b,tpos,ret=0;
  480.     char *classbuf,**classlist,*classarray,**classtypeid,**classrecog,buf[256],buf2[256];
  481.     struct DOpusRemember *key;
  482.  
  483.     filereq.flags=0;
  484.     filereq.title=cfg_string[STR_SELECT_CLASS_FILE_TO_LOAD];
  485.     strcpy(dirbuf,classname);
  486.     if (classbuf=BaseName(dirbuf)) *classbuf=0;
  487.     filebuf[0]=0;
  488.     filereq.window=Window;
  489.     if (!(FileRequest(&filereq)) || !filebuf[0]) return(0);
  490.     strcpy(buf,dirbuf); TackOn(buf,filebuf,256);
  491.  
  492.     while (!(in=Open(buf,MODE_OLDFILE))) {
  493.         lsprintf(buf2,cfg_string[STR_OPEN_FAILED],IoErr());
  494.         if (!(request(buf2))) return(0);
  495.     }
  496.  
  497.     key=NULL;
  498.  
  499.     if ((CheckExist(buf,&size))>=0 ||
  500.         !(classbuf=LAllocRemember(&key,size+2,MEMF_CLEAR))) {
  501.         Close(in);
  502.         return(0);
  503.     }
  504.  
  505.     Read(in,classbuf,size);
  506.     Close(in);
  507.  
  508.     for (a=0,num=0;a<size;a++) if (!classbuf[a]) ++num;
  509.     num/=2;
  510.  
  511.     if ((classlist=LAllocRemember(&key,(num+1)*4,MEMF_CLEAR)) &&
  512.         (classtypeid=LAllocRemember(&key,(num+1)*4,MEMF_CLEAR)) &&
  513.         (classrecog=LAllocRemember(&key,(num+1)*4,MEMF_CLEAR)) &&
  514.         (classarray=LAllocRemember(&key,num+1,MEMF_CLEAR))) {
  515.         pos=0; a=0;
  516.         FOREVER {
  517.             tpos=pos;
  518.             if ((pos=readline(classbuf,pos,buf,size))==-1) break;
  519.             classlist[a]=&classbuf[tpos];
  520.             classtypeid[a]="";
  521.             for (b=0;buf[b];b++) {
  522.                 if (buf[b]==1) {
  523.                     classbuf[tpos+b]=0;
  524.                     classtypeid[a]=&classbuf[tpos+b+1];
  525.                     ++b;
  526.                     break;
  527.                 }
  528.             }
  529.             for (;buf[b];b++);
  530.             classrecog[a++]=&classbuf[tpos+b+1];
  531.             for (lsize=tpos+b+1;lsize<size;lsize++)
  532.                 if (!classbuf[lsize]) break;
  533.             pos=lsize+1;
  534.         }
  535.         if (classlist[0] &&
  536.             (dolistwindow(cfg_string[STR_SELECT_CLASSES_TO_IMPORT],332,72,
  537.                 classlist,DLVF_MULTI|DLVF_HIREC,classarray,NULL))) {
  538.             for (a=0;a<num;a++) {
  539.                 if (classarray[a]) {
  540.                     if (!(addfileclass(classlist[a],classtypeid[a],classrecog[a]))) break;
  541.                     ret=1;
  542.                 }
  543.             }
  544.         }
  545.     }
  546.     LFreeRemember(&key);
  547.     return(ret);
  548. }
  549.  
  550. savefileclasses()
  551. {
  552.     struct fileclass *class;
  553.     int out,a;
  554.     char f=0,g=1,buf[100];
  555.  
  556.     if (!firstclass) return(1);
  557.     if (!classname[0]) strcpy(classname,"s:DirectoryOpus.CLA");
  558.     while (!(out=Open(classname,MODE_NEWFILE))) {
  559.         lsprintf(buf,cfg_string[STR_SAVE_FAILED],IoErr());
  560.         if (!(request(buf))) return(0);
  561.     }
  562.     class=firstclass;
  563.     while (class) {
  564.         if (class->type[0]) {
  565.             if ((Write(out,class->type,(a=strlen(class->type))))<a) break;
  566.             if (class->typeid[0]) {
  567.                 Write(out,&g,1);
  568.                 if ((Write(out,class->typeid,(a=strlen(class->typeid))))<a) break;
  569.             }
  570.         }
  571.         Write(out,&f,1);
  572.         if (class->recognition) {
  573.             if ((Write(out,class->recognition,(a=(strlen(class->recognition)+1))))<a)
  574.                 break;
  575.         }
  576.         else Write(out,&f,1);
  577.         class=class->next;
  578.     }
  579.     Close(out);
  580.     return(1);
  581. }
  582.  
  583. addfileclass(type,typeid,recog)
  584. char *type,*typeid,*recog;
  585. {
  586.     struct fileclass *class,*newclass,*last;
  587.  
  588.     class=firstclass;
  589.     while (class) {
  590.         if (LStrCmpI(class->type,type)>=0) break;
  591.         if (!class->next) last=class;
  592.         class=class->next;
  593.     }
  594.     if (!(newclass=AllocMem(sizeof(struct fileclass),MEMF_CLEAR))) return(0);
  595.     if (class) {
  596.         if (class->last) {
  597.             class->last->next=newclass;
  598.             newclass->last=class->last;
  599.         }
  600.         else if (class==firstclass) firstclass=newclass;
  601.         newclass->next=class;
  602.         class->last=newclass;
  603.     }
  604.     else if (firstclass) {
  605.         last->next=newclass;
  606.         newclass->last=last;
  607.     }
  608.     else firstclass=newclass;
  609.     strcpy(newclass->type,type);
  610.     strcpy(newclass->typeid,typeid);
  611.     if (recog && (newclass->recognition=AllocMem(strlen(recog)+1,MEMF_CLEAR)))
  612.         strcpy(newclass->recognition,recog);
  613.     return(1);
  614. }
  615.  
  616. void freefileclasses()
  617. {
  618.     struct fileclass *class,*newclass;
  619.  
  620.     class=firstclass;
  621.     while (class) {
  622.         newclass=class->next;
  623.         freestring(class->recognition);
  624.         FreeMem(class,sizeof(struct fileclass));
  625.         class=newclass;
  626.     }
  627.     firstclass=NULL;
  628. }
  629.  
  630. void removefileclass(class)
  631. struct fileclass *class;
  632. {
  633.     if (class->last) class->last->next=class->next;
  634.     if (class->next) class->next->last=class->last;
  635.     if (class==firstclass) firstclass=class->next;
  636.     freestring(class->recognition);
  637.     FreeMem(class,sizeof(struct fileclass));
  638. }
  639.  
  640. char **makeclasslist(key)
  641. struct DOpusRemember **key;
  642. {
  643.     char **list;
  644.     int count,a;
  645.     struct fileclass *class;
  646.  
  647.     LFreeRemember(key);
  648.     if (!firstclass) return(NULL);
  649.     class=firstclass;
  650.     for (count=0;class;count++,class=class->next);
  651.     if (!(list=LAllocRemember(key,(count+1)*4,MEMF_CLEAR))) return(NULL);
  652.     class=firstclass;
  653.     for (a=0;a<count;a++) {
  654.         if (list[a]=LAllocRemember(key,40,MEMF_CLEAR)) strcpy(list[a],class->type);
  655.         class=class->next;
  656.     }
  657.     return(list);
  658. }
  659.  
  660. readline(buf,pos,buf1,size)
  661. char *buf;
  662. int pos;
  663. char *buf1;
  664. int size;
  665. {
  666.     int a;
  667.  
  668.     for (a=0;a<256;a++) {
  669.         if (size==pos || buf[pos]==0) {
  670.             buf1[a]=0;
  671.             if (size==pos) return(-1);
  672.             return(pos+1);
  673.         }
  674.         buf1[a]=buf[pos];
  675.         ++pos;
  676.     }
  677.     buf1[pos]=0;
  678.     return(pos);
  679. }
  680.  
  681. editfileclass(fclass,new)
  682. struct fileclass *fclass;
  683. int new;
  684. {
  685.     int a,b,old,selitem,lasta=-1,x,y,mx,my,off,temp,waitbits,remapp=0;
  686.     ULONG class,sec,mic,oldsec,oldmic;
  687.     USHORT code,gadgetid;
  688.     struct Gadget *gad;
  689.     struct DOpusListView *view;
  690.     struct DOpusRemember *key=NULL;
  691.     char
  692.         *classlist[MAXFUNCS+1],classtype[MAXFUNCS],*displist[MAXFUNCS+1],
  693.         *templist,temptype;
  694.  
  695.     for (a=0;a<MAXFUNCS;a++) {
  696.         displist[a]=LAllocRemember(&key,80,MEMF_CLEAR);
  697.         classlist[a]=NULL;
  698.     }
  699.     makeeditclasslist(fclass,classlist,classtype);
  700.     dispclasslist(classlist,classtype,displist);
  701.  
  702.     namesinfo.MaxChars=32;
  703.     strcpy(edit_namebuf,fclass->type);
  704.     strcpy(edit_typeidbuf,fclass->typeid);
  705.     edit_funcbuf[0]=0; edit_pathbuf[0]=0;
  706.     editclassgadgets[4].Flags&=~SELECTED;
  707.  
  708.     AddGadgetBorders(&key,
  709.         &editclassgadgets[2],
  710.         4,
  711.         screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
  712.     AddGadgetBorders(&key,
  713.         &editclassgadgets[6],
  714.         3,
  715.         screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
  716.     AddGadgetBorders(&key,
  717.         &editclassgadgets[10],
  718.         1,
  719.         screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
  720.     AddGadgetBorders(&key,
  721.         &editclassgadgets[12],
  722.         2,
  723.         screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen);
  724.  
  725.     SetAPen(rp,screen_pens[1].pen);
  726.     AddGadgets(Window,
  727.         editclassgadgets,
  728.         editclassgads,
  729.         14,
  730.         screen_pens[config->gadgettopcol].pen,screen_pens[config->gadgetbotcol].pen,1);
  731.     doglassimage(&editclassgadgets[6]);
  732.     doglassimage(&editclassgadgets[8]);
  733.     Do3DBox(rp,
  734.         x_off+37,y_off+140,
  735.         116,12,
  736.         screen_pens[config->gadgetbotcol].pen,screen_pens[config->gadgettopcol].pen);
  737.  
  738.     fileview_buf=NULL; fileview_lines=fileview_topline=0; fileview_type=1;
  739.     draw_file_view();
  740.  
  741.     showclassop(0);
  742.     seteditclassgads(0);
  743.     setuplist(&editclasslist,7,88);
  744.     editclasslist.topitem=0; editclasslist.itemselected=-1;
  745.     editclasslist.items=displist;
  746.     AddListView(&editclasslist,1);
  747.     initsidegads(editfuncgads,0,0);
  748.     ClearMenuStrip(Window);
  749.     Window->Flags|=WFLG_RMBTRAP;
  750.     selitem=-1;
  751.     if (new) ActivateStrGad(&editclassgadgets[0],Window);
  752.     oldsec=oldmic=0;
  753.  
  754.     if (!appobject) {
  755.         add_appobject(0);
  756.         remapp=1;
  757.     }
  758.  
  759.     waitbits=1<<Window->UserPort->mp_SigBit;
  760.     if (appobject) waitbits|=1<<appport->mp_SigBit;
  761.  
  762.     FOREVER {
  763.         if (appobject) {
  764.             while (appmsg=(struct AppMessage *)GetMsg(appport)) {
  765.                 ActivateWindow(Window);
  766.                 if (appmsg->am_ID==MY_APPOBJECT &&
  767.                     appmsg->am_NumArgs>0 &&
  768.                     (*appmsg->am_ArgList[0].wa_Name)) {
  769.                     PathName(appmsg->am_ArgList[0].wa_Lock,edit_pathbuf,256);
  770.                     TackOn(edit_pathbuf,appmsg->am_ArgList[0].wa_Name,256);
  771.                     RefreshStrGad(&editclassgadgets[9],Window);
  772.                     load_file_view();
  773.                 }
  774.                 ReplyMsg((struct Message *)appmsg);
  775.             }
  776.         }
  777.         while (IMsg=getintuimsg()) {
  778.             if ((view=ListViewIDCMP(&editclasslist,IMsg))==(struct DOpusListView *)-1) {
  779.                 class=IMsg->Class; code=IMsg->Code;
  780.                 mx=IMsg->MouseX; my=IMsg->MouseY;
  781.                 sec=IMsg->Seconds; mic=IMsg->Micros;
  782.                 if (class==IDCMP_GADGETUP || class==IDCMP_GADGETDOWN) {
  783.                     gad=(struct Gadget *)IMsg->IAddress;
  784.                     gadgetid=gad->GadgetID;
  785.                 }
  786.                 ReplyMsg((struct Message *)IMsg);
  787.                 switch (class) {
  788.                     case IDCMP_MOUSEBUTTONS:
  789.                         if (code!=SELECTDOWN ||
  790.                             mx<x_off+11 || mx>x_off+505 ||
  791.                             my<y_off+21 || my>x_off+68) break;
  792.                         if (oldsec && DoubleClick(oldsec,oldmic,sec,mic)) off=1;
  793.                         else off=0;
  794.                         oldsec=sec; oldmic=mic;
  795.                         FOREVER {
  796.                             if (my>y_off+20 && my<y_off+69) {
  797.                                 x=((mx-x_off-11)/8)-10;
  798.                                 if (x<0) x=0;
  799.                                 y=((my-y_off-21)/8)+fileview_topline;
  800.                                 if (y<fileview_topline) y=fileview_topline;
  801.                                 if (x<36) {
  802.                                     if ((x%9)==8) --x;
  803.                                     a=x/9; x=(a*4)+((x%9)/2);
  804.                                 }
  805.                                 else if (x>35) {
  806.                                     x-=36;
  807.                                     if (x>15) x=15;
  808.                                 }
  809.                                 if (off) {
  810.                                     a=(y*16)+x;
  811.                                     if (a==fileview_position) {
  812.                                         old=fileview_offset;
  813.                                         if ((fileview_offset=a)<0 ||
  814.                                             fileview_offset>=fileview_size) fileview_offset=-1;
  815.                                         a=0; b=1;
  816.                                     }
  817.                                     else {
  818.                                         a=-1;
  819.                                         off=0;
  820.                                     }
  821.                                 }
  822.                                 else {
  823.                                     old=fileview_position;
  824.                                     if ((fileview_position=(y*16)+x)<0 ||
  825.                                         fileview_position>=fileview_size) fileview_position=-1;
  826.                                     a=fileview_position; b=0;
  827.                                     if (fileview_offset>fileview_position) show_view_number(-1,1);
  828.                                     else if (fileview_offset>-1)
  829.                                         show_view_number(fileview_position-fileview_offset,1);
  830.                                 }
  831.                                 if (a>-1 && a!=old) {
  832.                                     fileview_oldtop=-1;
  833.                                     show_file_view();
  834.                                     show_view_number(a,b);
  835.                                 }
  836.                             }
  837.                             if (off) break;
  838.                             class=0;
  839.                             while (IMsg=getintuimsg()) {
  840.                                 if (IMsg->Class==IDCMP_MOUSEMOVE || IMsg->Class==IDCMP_MOUSEBUTTONS)
  841.                                     class=IMsg->Class; code=IMsg->Code;
  842.                                 ReplyMsg((struct Message *)IMsg);
  843.                                 if (class==IDCMP_MOUSEBUTTONS && code==SELECTUP) break;
  844.                             }
  845.                             if (class==IDCMP_MOUSEBUTTONS && code==SELECTUP) break;
  846.                             mx=Window->MouseX;
  847.                             my=Window->MouseY;
  848.                             if (my<y_off+21) {
  849.                                 my=y_off+21;
  850.                                 if (fileview_topline>0) {
  851.                                     --fileview_topline; fileview_oldtop=fileview_position=-1;
  852.                                     show_file_view();
  853.                                     FixSliderPot(Window,&editclassgadgets[11],fileview_topline,fileview_lines,6,1);
  854.                                 }
  855.                             }
  856.                             else if (my>y_off+68) {
  857.                                 my=y_off+68;
  858.                                 if (fileview_topline<fileview_lines-6) {
  859.                                     ++fileview_topline; fileview_oldtop=fileview_position=-1;
  860.                                     show_file_view();
  861.                                     FixSliderPot(Window,&editclassgadgets[11],fileview_topline,fileview_lines,6,1);
  862.                                 }
  863.                             }
  864.                             else if (class!=IDCMP_MOUSEMOVE) Wait(1<<Window->UserPort->mp_SigBit);
  865.                         }
  866.                         break;
  867.  
  868.                     case IDCMP_RAWKEY:
  869.                         switch (code) {
  870.                             case CURSORUP:
  871.                                 if (fileview_position>15) cursor_fileview(-16);
  872.                                 break;
  873.                             case CURSORDOWN:
  874.                                 if (fileview_position<fileview_size-16) cursor_fileview(16);
  875.                                 break;
  876.                             case CURSORLEFT:
  877.                                 if (fileview_position) cursor_fileview(-1);
  878.                                 break;
  879.                             case CURSORRIGHT:
  880.                                 if (fileview_position<fileview_size-1) cursor_fileview(1);
  881.                                 break;
  882.                             case 0x23:
  883.                                 ActivateStrGad(&editclassgadgets[0],Window);
  884.                                 break;
  885.                             case 0x17:
  886.                                 ActivateStrGad(&editclassgadgets[1],Window);
  887.                                 break;
  888.                             case 0x34:
  889.                                 goto getfileview;
  890.                         }
  891.                         break;
  892.  
  893.                     case IDCMP_GADGETDOWN:
  894.                         switch (gadgetid) {
  895.                             case CLASS_VIEWUP:
  896.                             case CLASS_VIEWDOWN:
  897.                             case CLASS_VIEWSLIDER:
  898.                                 temp=0;
  899.                                 FOREVER {
  900.                                     if (gadgetid==CLASS_VIEWUP) {
  901.                                         if (fileview_topline==0) break;
  902.                                         --fileview_topline;
  903.                                     }
  904.                                     else if (gadgetid==CLASS_VIEWDOWN) {
  905.                                         if (fileview_topline>=fileview_lines-6) break;
  906.                                         ++fileview_topline;
  907.                                     }
  908.                                     else {
  909.                                         fileview_topline=GetSliderPos(&editclassgadgets[11],fileview_lines,6);
  910.                                     }
  911.                                     if (fileview_topline!=fileview_oldtop) show_file_view();
  912.                                     if (gadgetid!=CLASS_VIEWSLIDER) {
  913.                                         FixSliderPot(Window,&editclassgadgets[11],fileview_topline,fileview_lines,6,1);
  914.                                         if (!temp++) Delay(10);
  915.                                     }
  916.                                     while (IMsg=getintuimsg()) {
  917.                                         class=IMsg->Class; code=IMsg->Code;
  918.                                         ReplyMsg((struct Message *)IMsg);
  919.                                         if (class==IDCMP_MOUSEBUTTONS && code==SELECTUP)
  920.                                             class=IDCMP_GADGETUP;
  921.                                         if (class==IDCMP_GADGETUP) break;
  922.                                     }
  923.                                     if (class==IDCMP_GADGETUP) break;
  924.                                 }
  925.                                 ShowSlider(Window,&editclassgadgets[11]);
  926.                                 break;
  927.                         }
  928.                         break;
  929.  
  930.                     case IDCMP_GADGETUP:
  931.                         switch (gadgetid) {
  932.                             case CLASS_OKAY:
  933.                                 makeclassrecog(fclass,classlist,classtype);
  934.                                 strcpy(fclass->type,edit_namebuf);
  935.                                 strcpy(fclass->typeid,edit_typeidbuf);
  936.                             case CLASS_CANCEL:
  937.                                 if (editclassgadgets[3].Flags&GFLG_DISABLED) seteditclassgads(1);
  938.                                 RemoveListView(&editclasslist,1);
  939.                                 LFreeRemember(&key);
  940.                                 freefunclist(classlist);
  941.                                 Window->Flags&=~WFLG_RMBTRAP;
  942.                                 FSSetMenuStrip(Window,&projectmenu);
  943.                                 if (remapp) rem_appobject(0);
  944.                                 return((gadgetid==CLASS_OKAY));
  945.  
  946.                             case CLASS_OPERATION:
  947.                                 checkclassswap();
  948.                                 if ((a=funcrequester(FREQ_FILETYPE,
  949.                                     NULL,cfg_string[STR_LIST_OF_FILETYPE_COMMANDS]))) {
  950.                                     classtype[selitem]=a;
  951.                                     showclassop(classtype[selitem]);
  952.                                     ActivateStrGad(&editclassgadgets[7],Window);
  953.                                 }
  954.                                 break;
  955.  
  956.                             case CLASS_DELETE:
  957.                                 edit_funcbuf[0]=0; classtype[selitem]=0;
  958.                             case CLASS_FUNC:
  959.                                 lasta=-1;
  960.                             case CLASS_NEWENTRY:
  961.                                 checkclassswap();
  962.                                 a=-1;
  963.                                 if (selitem>-1) {
  964.                                     if (gadgetid==CLASS_NEWENTRY && !edit_funcbuf[0]) {
  965.                                         ActivateStrGad(&editclassgadgets[7],Window);
  966.                                         break;
  967.                                     }
  968.                                     editclasslist.itemselected=-1;
  969.                                     if (!edit_funcbuf[0]) lasta=-1;
  970.                                     endclassedit(selitem,classlist,classtype,displist);
  971.                                     if (lasta==-1) a=selitem;
  972.                                     else a=lasta+1;
  973.                                     selitem=-1;
  974.                                 }
  975.                                 if (gadgetid==CLASS_NEWENTRY) {
  976.                                     if (editclasslist.count>=MAXFUNCS) break;
  977.                                     if (a>-1) selitem=a;
  978.                                     else {
  979.                                         selitem=editclasslist.count;
  980.                                         seteditclassgads(1);
  981.                                     }
  982.                                     insertnewclass(classlist,classtype,selitem,displist," ",2);
  983.                                     lasta=selitem;
  984.                                 }
  985.                                 else seteditclassgads(0);
  986.                                 break;
  987.  
  988.                             case CLASS_DUPLICATE:
  989.                                 checkclassswap();
  990.                                 if (editclasslist.count>=MAXFUNCS || !edit_funcbuf[0]) {
  991.                                     ActivateStrGad(&editclassgadgets[7],Window);
  992.                                     break;
  993.                                 }
  994.                                 editclasslist.itemselected=-1;
  995.                                 endclassedit(selitem,classlist,classtype,displist);
  996.                                 a=selitem; selitem=editclasslist.count;
  997.                                 insertnewclass(classlist,classtype,selitem,displist,classlist[a],classtype[a]);
  998.                                 break;
  999.  
  1000.                             case CLASS_FILEVIEWREQ:
  1001. getfileview:
  1002.                                 if (!(funcrequester(FREQ_GENERIC,edit_pathbuf,NULL))) break;
  1003.                                 RefreshStrGad(&editclassgadgets[9],Window);
  1004.                             case CLASS_FILEVIEW:
  1005.                                 if (code!=0x9) load_file_view();
  1006.                                 break;
  1007.                             case CLASS_HEXDEC:
  1008.                                 fileview_type=1-fileview_type;
  1009.                                 DoCycleGadget(&editclassgadgets[10],Window,fileview_types,fileview_type);
  1010.                                 show_view_number(fileview_position,0);
  1011.                                 if (fileview_offset>fileview_position) show_view_number(-1,1);
  1012.                                 else if (fileview_offset>-1)
  1013.                                     show_view_number(fileview_position-fileview_offset,1);
  1014.                                 break;
  1015.                             case CLASS_TYPE:
  1016.                                 ActivateStrGad(&editclassgadgets[1],Window);
  1017.                                 break;
  1018.                             case CLASS_TYPEID:
  1019.                                 StrToUpper(edit_typeidbuf,edit_typeidbuf);
  1020.                                 RefreshStrGad(&editclassgadgets[1],Window);
  1021.                                 break;
  1022.                         }
  1023.                         break;
  1024.                 }
  1025.             }
  1026.             else if (view) {
  1027.                 do {
  1028.                     if (selitem!=-1) {
  1029.                         endclassedit(selitem,classlist,classtype,displist);
  1030.                         if (editclassgadgets[4].Flags&SELECTED) {
  1031.                             checkclassswap();
  1032.                             seteditclassgads(0);
  1033.                             templist=classlist[selitem];
  1034.                             classlist[selitem]=classlist[view->itemselected];
  1035.                             classlist[view->itemselected]=templist;
  1036.                             temptype=classtype[selitem];
  1037.                             classtype[selitem]=classtype[view->itemselected];
  1038.                             classtype[view->itemselected]=temptype;
  1039.                             dispclasslist(classlist,classtype,displist);
  1040.                             editclasslist.itemselected=-1;
  1041.                             RefreshListView(&editclasslist,1);
  1042.                             selitem=-1;
  1043.                             break;
  1044.                         }
  1045.                     }
  1046.                     else seteditclassgads(1);
  1047.                     selitem=view->itemselected;
  1048.                     if (classlist[selitem]) strcpy(edit_funcbuf,classlist[selitem]);
  1049.                     else edit_funcbuf[0]=0;
  1050.                     RefreshStrGad(&editclassgadgets[7],Window);
  1051.                     showclassop(classtype[selitem]);
  1052.                     ActivateStrGad(&editclassgadgets[7],Window);
  1053.                 }
  1054.                 while (0);
  1055.             }
  1056.         }
  1057.         Wait(waitbits);
  1058.     }
  1059. }
  1060.  
  1061. void makeeditclasslist(class,classlist,classtype)
  1062. struct fileclass *class;
  1063. char **classlist,*classtype;
  1064. {
  1065.     int a,b,len,type,pos,num;
  1066.     char buf[256];
  1067.  
  1068.     if (!class->recognition) return;
  1069.     len=strlen(class->recognition);
  1070.     type=-1; pos=num=0;
  1071.     for (a=0;a<=len;a++) {
  1072.         if (type==-1) {
  1073.             if (class->recognition[a]<FTYC_COMMANDOK) {
  1074.                 type=class->recognition[a];
  1075.                 continue;
  1076.             }
  1077.             if (class->recognition[a]>FTYC_ENDLIMIT &&
  1078.                 class->recognition[a]<FTYC_ENDSECTION) {
  1079. doandor:
  1080.                 classlist[num]=getcopy(" ",2,NULL);
  1081.                 for (b=0;b<11;b++) {
  1082.                     if (classopvals[b]==class->recognition[a]) {
  1083.                         classtype[num]=b+1;
  1084.                         break;
  1085.                     }
  1086.                 }
  1087.                 if ((++num)==MAXFUNCS) break;
  1088.             }
  1089.         }
  1090.         else if (pos==255 || class->recognition[a]>FTYC_ENDLIMIT ||
  1091.             !class->recognition[a]) {
  1092.             buf[pos]=0;
  1093.             if (classlist[num]=getcopy(buf,-1,NULL)) {
  1094.                 for (b=0;b<11;b++) {
  1095.                     if (classopvals[b]==type) {
  1096.                         classtype[num]=b+1;
  1097.                         break;
  1098.                     }
  1099.                 }
  1100.                 if ((++num)==MAXFUNCS) break;
  1101.             }
  1102.             pos=0; type=-1;
  1103.             if (class->recognition[a]>FTYC_ENDLIMIT &&
  1104.                 class->recognition[a]<FTYC_ENDSECTION) goto doandor;
  1105.         }
  1106.         else buf[pos++]=class->recognition[a];
  1107.     }
  1108.     for (a=num;a<MAXFUNCS;a++) classlist[a]=NULL;
  1109. }
  1110.  
  1111. void dispclasslist(classlist,classtype,displist)
  1112. char **classlist,*classtype,**displist;
  1113. {
  1114.     int a;
  1115.     char buf[80],*ptr;
  1116.  
  1117.     for (a=0;a<MAXFUNCS;a++) {
  1118.         if (!classlist[a]) break;
  1119.         strcpy(buf,classopslist[classtype[a]-1]);
  1120.         ptr=strchr(buf,' '); *ptr=0;
  1121.         StrCombine(displist[a],buf,spacestring,15);
  1122.         if (classopvals[classtype[a]-1]<FTYC_COMMANDOK) StrConcat(displist[a],classlist[a],75);
  1123.     }
  1124.     for (;a<MAXFUNCS;a++) displist[a][0]=0;
  1125. }
  1126.  
  1127. void seteditclassgads(on)
  1128. int on;
  1129. {
  1130.     int a;
  1131.  
  1132.     if (on) {
  1133.         for (a=3;a<6;a++) EnableGadget(&editclassgadgets[a],rp,4,2);
  1134.         EnableGadget(&editclassgadgets[6],rp,4,2);
  1135.         EnableGadget(&editclassgadgets[7],rp,0,0);
  1136.     }
  1137.     else {
  1138.         for (a=3;a<6;a++) DisableGadget(&editclassgadgets[a],rp,4,2);
  1139.         DisableGadget(&editclassgadgets[6],rp,4,2);
  1140.         DisableGadget(&editclassgadgets[7],rp,0,0);
  1141.     }
  1142. }
  1143.  
  1144. void removeclassentry(classlist,classtype,entry)
  1145. char **classlist,*classtype;
  1146. int entry;
  1147. {
  1148.     if (entry<MAXFUNCS-1) {
  1149.         CopyMem(&classlist[entry+1],&classlist[entry],(MAXFUNCS-1-entry)*4);
  1150.         CopyMem(&classtype[entry+1],&classtype[entry],(MAXFUNCS-1-entry));
  1151.     }
  1152.     classlist[MAXFUNCS-1]=NULL;
  1153. }
  1154.  
  1155. void insertnewclass(classlist,classtype,entry,displist,string,type)
  1156. char **classlist,*classtype;
  1157. int entry;
  1158. char **displist,*string;
  1159. int type;
  1160. {
  1161.     char *templist[MAXFUNCS],temptype[MAXFUNCS];
  1162.     int a;
  1163.  
  1164.     a=MAXFUNCS-entry-1;
  1165.     CopyMem(&classlist[entry],templist,a*4);
  1166.     CopyMem(templist,&classlist[entry+1],a*4);
  1167.     classlist[entry]=getcopy(string,-1,NULL);
  1168.     CopyMem(&classtype[entry],temptype,a);
  1169.     CopyMem(temptype,&classtype[entry+1],a);
  1170.     classtype[entry]=type;
  1171.     dispclasslist(classlist,classtype,displist);
  1172.     if (entry<editclasslist.topitem ||
  1173.         entry>=editclasslist.topitem+editclasslist.lines) editclasslist.topitem=entry;
  1174.     editclasslist.itemselected=entry;
  1175.     RefreshListView(&editclasslist,1);
  1176.     if (string[0]==' ' && string[1]==0) edit_funcbuf[0]=0;
  1177.     else strcpy(edit_funcbuf,string);
  1178.     RefreshStrGad(&editclassgadgets[7],Window);
  1179.     showclassop(type);
  1180.     ActivateStrGad(&editclassgadgets[7],Window);
  1181. }
  1182.  
  1183. void endclassedit(item,classlist,classtype,displist)
  1184. int item;
  1185. char **classlist,*classtype,**displist;
  1186. {
  1187.     freestring(classlist[item]);
  1188.     if (classtype[item]<1 || classopvals[classtype[item]-1]<FTYC_COMMANDOK) {
  1189.         if (edit_funcbuf[0]) classlist[item]=getcopy(edit_funcbuf,-1,NULL);
  1190.         else removeclassentry(classlist,classtype,item);
  1191.     }
  1192.     else classlist[item]=getcopy(" ",2,NULL);
  1193.     dispclasslist(classlist,classtype,displist);
  1194.     RefreshListView(&editclasslist,1);
  1195.     edit_funcbuf[0]=0;
  1196.     RefreshStrGad(&editclassgadgets[7],Window);
  1197.     showclassop(0);
  1198. }
  1199.  
  1200. void makeclassrecog(class,classlist,classtype)
  1201. struct fileclass *class;
  1202. unsigned char **classlist,*classtype;
  1203. {
  1204.     int size,num,a;
  1205.     unsigned char *buf,buf2[2];
  1206.  
  1207.     size=num=0;
  1208.     for (a=0;a<MAXFUNCS;a++) {
  1209.         if (!classlist[a]) break;
  1210.         size+=strlen(classlist[a])+2;
  1211.         ++num;
  1212.     }
  1213.     freestring(class->recognition); class->recognition=NULL;
  1214.     if (!size) return;
  1215.     if (!(buf=AllocMem(size+2,MEMF_CLEAR))) return;
  1216.     buf2[1]=0;
  1217.     for (a=0;a<num;a++) {
  1218.         buf2[0]=classopvals[classtype[a]-1];
  1219.         strcat(buf,buf2);
  1220.         if (buf2[0]<FTYC_COMMANDOK) {
  1221.             strcat(buf,classlist[a]);
  1222.             if (a==(num-1) || classopvals[classtype[a+1]-1]<FTYC_COMMANDOK) {
  1223.                 buf2[0]=FTYC_ENDSECTION;
  1224.                 strcat(buf,buf2);
  1225.             }
  1226.         }
  1227.     }
  1228.     class->recognition=getcopy(buf,-1,NULL);
  1229.     FreeMem(buf,size+2);
  1230. }
  1231.  
  1232. void checkclassswap()
  1233. {
  1234.     if (editclassgadgets[4].Flags&SELECTED) {
  1235.         editclassgadgets[4].Flags&=~SELECTED;
  1236.         select_gadget(&editclassgadgets[4],0);
  1237.     }
  1238. }
  1239.  
  1240. void showclassop(op)
  1241. int op;
  1242. {
  1243.     char str[80],*ptr;
  1244.     int x,a;
  1245.  
  1246.     SetAPen(rp,screen_pens[0].pen);
  1247.     RectFill(rp,
  1248.         x_off+37,y_off+140,
  1249.         x_off+152,y_off+151);
  1250.     SetAPen(rp,screen_pens[1].pen);
  1251.     if (op<1) ptr="----";
  1252.     else {
  1253.         strcpy(str,classopslist[op-1]);
  1254.         ptr=strchr(str,' '); *ptr=0;
  1255.         ptr=str;
  1256.     }
  1257.     a=strlen(ptr);
  1258.     x=((116-(a*8))/2)+x_off+37;
  1259.     Move(rp,x,y_off+148);
  1260.     Text(rp,ptr,a);
  1261. }
  1262.  
  1263. struct fileclass *getfileclasslist(type)
  1264. int type;
  1265. {
  1266.     struct DOpusRemember *key=NULL;
  1267.     int a;
  1268.     struct fileclass *fclass=NULL;
  1269.  
  1270.     fileclasslist=makeclasslist(&key);
  1271.     if ((a=funcrequester(FREQ_FILECLASS,NULL,fileclasstype[type]))) {
  1272.         fclass=firstclass;
  1273.         while ((--a) && fclass && fclass->next) fclass=fclass->next;
  1274.     }
  1275.     LFreeRemember(&key);
  1276.     return(fclass);
  1277. }
  1278.  
  1279. void draw_file_view()
  1280. {
  1281.     int a;
  1282.  
  1283.     SetAPen(rp,screen_pens[0].pen);
  1284.     RectFill(rp,
  1285.         y_off+7,y_off+21,
  1286.         x_off+511,y_off+68);
  1287.     do3dbox(x_off+7,y_off+21,505,48);
  1288.     Do3DBox(rp,
  1289.         x_off+534,y_off+31,
  1290.         91,12,
  1291.         screen_pens[config->gadgetbotcol].pen,screen_pens[config->gadgettopcol].pen);
  1292.     Do3DBox(rp,
  1293.         x_off+534,y_off+57,
  1294.         91,12,
  1295.         screen_pens[config->gadgetbotcol].pen,screen_pens[config->gadgettopcol].pen);
  1296.     SetAPen(rp,screen_pens[1].pen);
  1297.     UScoreText(rp,
  1298.         cfg_string[STR_POSITION],
  1299.         x_off+535,y_off+27,
  1300.         -1);
  1301.     UScoreText(rp,
  1302.         cfg_string[STR_OFFSET],
  1303.         x_off+535,y_off+53,
  1304.         -1);
  1305.     for (a=0;a<2;a++)
  1306.         DoArrow(rp,
  1307.             editclassgadgets[12+a].LeftEdge+2,editclassgadgets[12+a].TopEdge+1,
  1308.             12,6,
  1309.             screen_pens[1].pen,screen_pens[0].pen,a);
  1310.     fix_slider(&editclassgadgets[11]);
  1311.     FixSliderBody(Window,&editclassgadgets[11],fileview_lines,6,0);
  1312.     FixSliderPot(Window,&editclassgadgets[11],fileview_topline,fileview_lines,6,0);
  1313.     ShowSlider(Window,&editclassgadgets[11]);
  1314.     DoCycleGadget(&editclassgadgets[10],Window,fileview_types,fileview_type);
  1315. }
  1316.  
  1317. void free_file_view()
  1318. {
  1319.     int a;
  1320.  
  1321.     if (fileview_buf) {
  1322.         FreeMem(fileview_buf,fileview_size);
  1323.         fileview_buf=NULL;
  1324.     }
  1325.     fileview_size=fileview_lines=fileview_topline=0;
  1326.     fileview_oldtop=fileview_offset=fileview_position=-1;
  1327.     for (a=0;a<2;a++) show_view_number(-1,a);
  1328. }
  1329.  
  1330. void load_file_view()
  1331. {
  1332.     int file,rsize;
  1333.  
  1334.     free_file_view();
  1335.     busy();
  1336.     if ((CheckExist(edit_pathbuf,&fileview_size))<0 &&
  1337.         (file=Open(edit_pathbuf,MODE_OLDFILE))) {
  1338.         if (fileview_size>4096) fileview_size=4096;
  1339.         else if (fileview_size%16) fileview_size=((fileview_size+15)/16)*16;
  1340.         if (fileview_buf=AllocMem(fileview_size,MEMF_CLEAR)) {
  1341.             rsize=Read(file,fileview_buf,fileview_size);
  1342.             fileview_lines=(rsize+15)/16;
  1343.         }
  1344.         Close(file);
  1345.     }
  1346.     draw_file_view();
  1347.     if (!fileview_buf) {
  1348.         DisplayBeep(NULL);
  1349.         file_view_text(cfg_string[STR_FILE_NOT_FOUND],0);
  1350.     }
  1351.     else show_file_view();
  1352.     unbusy();
  1353. }
  1354.  
  1355. void file_view_text(txt,line)
  1356. char *txt;
  1357. int line;
  1358. {
  1359.     int len;
  1360.  
  1361.     SetAPen(rp,screen_pens[1].pen);
  1362.     SetBPen(rp,screen_pens[0].pen);
  1363.     Move(rp,x_off+9,y_off+27+(line*8));
  1364.     if (txt) Text(rp,txt,(len=strlen(txt)));
  1365.     else len=0;
  1366.     if (len<62) Text(rp,spacestring,62-len);
  1367. }
  1368.  
  1369. void show_file_view(void)
  1370. {
  1371.     int line,a,off,old,top,bottom,scroll,ox,px,aox,apx;
  1372.     char buf[80],buf2[30];
  1373.  
  1374.     top=0; bottom=5; scroll=0;
  1375.     if (fileview_oldtop>-1) {
  1376.         if ((a=fileview_topline-fileview_oldtop)>0 && a<6) {
  1377.             top=6-a;
  1378.             scroll=a*8;
  1379.         }
  1380.         else if (a<0 && a>-6) {
  1381.             bottom=-a-1;
  1382.             scroll=a*8;
  1383.         }
  1384.     }
  1385.     SetDrMd(rp,JAM2);
  1386.  
  1387.     for (line=0;line<6;line++) {
  1388.         if (line>=top && line<=bottom) {
  1389.             if (scroll) {
  1390.                 ScrollRaster(rp,0,scroll,x_off+7,y_off+21,x_off+511,y_off+68);
  1391.                 scroll=0;
  1392.             }
  1393.             if (fileview_lines<=line+fileview_topline) file_view_text(NULL,line);
  1394.             else {
  1395.                 off=(fileview_topline+line)*16;
  1396.                 lsprintf(buf,"%08lx: ",off);
  1397.                 old=off; ox=px=-1;
  1398.                 for (a=0;a<4;a++) {
  1399.                     lsprintf(buf2,"%02lx%02lx%02lx%02lx ",
  1400.                         fileview_buf[off++],fileview_buf[off++],fileview_buf[off++],fileview_buf[off++]);
  1401.                     strcat(buf,buf2);
  1402.                     if (px==-1 && fileview_position>=off-4 && fileview_position<off) {
  1403.                         apx=fileview_position-(off-4);
  1404.                         px=(a*9)+(apx*2); apx+=(a*4)+36;
  1405.                     }
  1406.                     if (ox==-1 && fileview_offset>=off-4 && fileview_offset<off) {
  1407.                         aox=fileview_offset-(off-4);
  1408.                         ox=(a*9)+(aox*2); aox+=(a*4)+36;
  1409.                     }
  1410.                 }
  1411.                 off=old;
  1412.                 for (a=0;a<16;a++,off++)
  1413.                     buf[46+a]=(isprint(fileview_buf[off]))?fileview_buf[off]:'.';
  1414.                 buf[62]=0;
  1415.                 file_view_text(buf,line);
  1416.                 if (px>-1 && px!=ox) {
  1417.                     SetDrMd(rp,COMPLEMENT);
  1418.                     RectFill(rp,
  1419.                         x_off+89+(px*8),y_off+21+(line*8),
  1420.                         x_off+104+(px*8),y_off+28+(line*8));
  1421.                     RectFill(rp,
  1422.                         x_off+89+(apx*8),y_off+21+(line*8),
  1423.                         x_off+96+(apx*8),y_off+28+(line*8));
  1424.                     SetDrMd(rp,JAM2);
  1425.                 }
  1426.                 if (ox>-1) {
  1427.                     SetAPen(rp,screen_pens[2].pen);
  1428.                     lsprintf(buf2,"%02lx",fileview_buf[fileview_offset]);
  1429.                     Move(rp,x_off+89+(ox*8),y_off+27+(line*8));
  1430.                     Text(rp,buf2,2);
  1431.                     buf2[0]=(isprint(fileview_buf[fileview_offset])?fileview_buf[fileview_offset]:'.');
  1432.                     Move(rp,x_off+89+(aox*8),y_off+27+(line*8));
  1433.                     Text(rp,buf2,1);
  1434.                     SetAPen(rp,screen_pens[1].pen);
  1435.                 }
  1436.             }
  1437.         }
  1438.     }
  1439.     fileview_oldtop=fileview_topline;
  1440. }
  1441.  
  1442. void show_view_number(num,pos)
  1443. int num,pos;
  1444. {
  1445.     char buf[20];
  1446.     int y;
  1447.  
  1448.     if (num<0) {
  1449.         SetAPen(rp,screen_pens[0].pen);
  1450.         RectFill(rp,
  1451.             x_off+534,y_off+31+(26*pos),
  1452.             x_off+624,y_off+42+(26*pos));
  1453.         SetAPen(rp,screen_pens[1].pen);
  1454.     }
  1455.     else {
  1456.         y=y_off+39+(26*pos);
  1457.         if (fileview_type==0) lsprintf(buf,"$%08lx",num);
  1458.         else lsprintf(buf,"%09ld",num);
  1459.         UScoreText(rp,buf,x_off+543,y,-1);
  1460.     }
  1461. }
  1462.  
  1463. void cursor_fileview(delta)
  1464. int delta;
  1465. {
  1466.     int ups=0;
  1467.  
  1468.     fileview_position+=delta;
  1469.     if (fileview_position<0) fileview_position=0;
  1470.     else if (fileview_position>=fileview_size) fileview_position=fileview_size-1;
  1471.  
  1472.     if (fileview_position<(fileview_topline*16)) {
  1473.         fileview_oldtop=-1;
  1474.         while (fileview_position<(fileview_topline*16)) {
  1475.             if (!fileview_topline) break;
  1476.             --fileview_topline;
  1477.         }
  1478.         ups=1;
  1479.     }
  1480.     else if (fileview_position>=((fileview_topline+6)*16)) {
  1481.         fileview_oldtop=-1;
  1482.         while (fileview_position>=((fileview_topline+6)*16)) {
  1483.             if (fileview_topline>=fileview_lines-6) break;
  1484.             ++fileview_topline;
  1485.         }
  1486.         ups=1;
  1487.     }
  1488.     show_file_view();
  1489.     show_view_number(fileview_position,0);
  1490.     if (fileview_offset>fileview_position) show_view_number(-1,1);
  1491.     else if (fileview_offset>-1)
  1492.         show_view_number(fileview_position-fileview_offset,1);
  1493.     if (ups) FixSliderPot(Window,&editclassgadgets[11],fileview_topline,fileview_lines,6,1);
  1494. }
  1495.